package com.novel.system.service.impl;

import com.novel.common.constants.UserConstants;
import com.novel.common.exception.business.BusinessException;
import com.novel.common.utils.StringUtils;
import com.novel.system.domain.SysDept;
import com.novel.system.domain.SysRole;
import com.novel.system.domain.vo.TreeData;
import com.novel.system.mapper.SysDeptMapper;
import com.novel.system.service.SysDeptService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 部门管理 服务实现
 *
 * @author novel
 * @since 2019/5/15
 */
@Service
public class SysDeptServiceImpl implements SysDeptService {
    private final SysDeptMapper deptMapper;

    public SysDeptServiceImpl(SysDeptMapper deptMapper) {
        this.deptMapper = deptMapper;
    }

    /**
     * 查询部门管理数据
     *
     * @return 部门信息集合
     */
    @Override
    public List<SysDept> selectDeptList(SysDept dept) {
        return deptMapper.selectDeptList(dept);
    }

    /**
     * 查询部门表格树
     *
     * @param dept 部门信息
     * @return 部门信息集合
     */
    @Override
    public List<SysDept> deptTreeTableData(SysDept dept) {
        List<SysDept> sysDeptList = deptMapper.selectDeptList(dept);
        return getTreeTableData(sysDeptList, 0);
    }

    /**
     * 查询部门管理树
     *
     * @return 所有部门信息
     */
    @Override
    public List<Map<String, Object>> selectDeptTree() {
        List<Map<String, Object>> trees;
        List<SysDept> deptList = selectDeptList(new SysDept());
        trees = getTrees(deptList, false, null);
        return trees;
    }

    /**
     * 根据角色ID查询部门（数据权限）
     *
     * @param role 角色对象
     * @return 部门列表（数据权限）
     */
    @Override
    public List<Map<String, Object>> roleDeptTreeData(SysRole role) {
        Long roleId = role.getId();
        List<Map<String, Object>> trees;
        List<SysDept> deptList = selectDeptList(new SysDept());
        if (StringUtils.isNotNull(roleId)) {
            List<String> roleDeptList = deptMapper.selectRoleDeptTree(roleId);
            trees = getTrees(deptList, true, roleDeptList);
        } else {
            trees = getTrees(deptList, false, null);
        }
        return trees;
    }

    /**
     * 对象转部门树
     *
     * @param deptList     部门列表
     * @param isCheck      是否需要选中
     * @param roleDeptList 角色已存在菜单列表
     * @return 树结构列表
     */
    private List<Map<String, Object>> getTrees(List<SysDept> deptList, boolean isCheck, List<String> roleDeptList) {

        List<Map<String, Object>> trees = new ArrayList<>();
        for (SysDept dept : deptList) {
            if (UserConstants.DEPT_NORMAL.equals(dept.getStatus())) {
                Map<String, Object> deptMap = new HashMap<>(5);
                deptMap.put("id", dept.getId());
                deptMap.put("pId", dept.getParentId());
                deptMap.put("name", dept.getDeptName());
                deptMap.put("title", dept.getDeptName());
                if (isCheck) {
                    deptMap.put("checked", roleDeptList.contains(dept.getId() + dept.getDeptName()));
                } else {
                    deptMap.put("checked", false);
                }
                trees.add(deptMap);
            }
        }
        return trees;
    }

    /**
     * 查询部门人数
     *
     * @param parentId 部门ID
     * @return 结果
     */
    @Override
    public boolean selectDeptCount(Long parentId) {
        SysDept dept = new SysDept();
        dept.setParentId(parentId);
        return deptMapper.selectDeptCount(dept) > 0;
    }

    /**
     * 查询部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkDeptExistUser(Long deptId) {
        int result = deptMapper.checkDeptExistUser(deptId);
        return result > 0;
    }

    /**
     * 删除部门管理信息
     *
     * @param deptId 部门ID
     * @return 结果
     */
    @Override
    public boolean deleteDeptById(Long deptId) {
        return deptMapper.deleteDeptById(deptId) > 0;
    }

    /**
     * 新增保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public boolean insertDept(SysDept dept) {
        SysDept info = deptMapper.selectDeptById(dept.getParentId());
        if (info != null) {
            dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
        } else {
            dept.setAncestors("0");
        }
        return deptMapper.insertDept(dept) > 0;
    }

    /**
     * 修改保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public boolean updateDept(SysDept dept) {
        SysDept info = deptMapper.selectDeptById(dept.getParentId());
        if (StringUtils.isNotNull(info)) {
            String ancestors = info.getAncestors() + "," + dept.getParentId();
            dept.setAncestors(ancestors);
            updateDeptChildren(dept.getId(), ancestors);
        }
        return deptMapper.updateDept(dept) > 0;
    }

    /**
     * 修改子元素关系
     *
     * @param deptId    部门ID
     * @param ancestors 元素列表
     */
    private void updateDeptChildren(Long deptId, String ancestors) {
        SysDept dept = new SysDept();
        dept.setParentId(deptId);
        List<SysDept> childrenList = deptMapper.selectDeptList(dept);
        for (SysDept children : childrenList) {
            children.setAncestors(ancestors + "," + dept.getParentId());
        }
        if (!childrenList.isEmpty()) {
            deptMapper.updateDeptChildren(childrenList);
        }
    }

    /**
     * 根据部门ID查询信息
     *
     * @param deptId 部门ID
     * @return 部门信息
     */
    @Override
    public SysDept selectDeptById(Long deptId) {
        return deptMapper.selectDeptById(deptId);
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public String checkDeptNameUnique(SysDept dept) {
        long deptId = StringUtils.isNull(dept.getId()) ? -1L : dept.getId();
        List<SysDept> deptList = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId());
        if (deptList != null) {
            for (SysDept sysDept : deptList) {
                if (StringUtils.isNotNull(sysDept) && sysDept.getId() != deptId) {
                    return UserConstants.DEPT_NAME_NOT_UNIQUE;
                }
            }
        }
        return UserConstants.DEPT_NAME_UNIQUE;
    }

    /**
     * 删除部门
     *
     * @param ids 部门id
     * @return 结果
     */

    @Override
    public boolean deleteMenuByIds(Long[] ids) {
        if (ids != null && ids.length > 0) {
            for (Long id : ids) {
                if (selectDeptCount(id)) {
                    throw new BusinessException("存在下级部门,不允许删除");
                }
                if (checkDeptExistUser(id)) {
                    throw new BusinessException("部门存在用户,不允许删除");
                }
            }
            return deptMapper.deleteDeptByIds(ids) > 0;
        } else {
            return false;
        }
    }

    @Override
    public List<TreeData> deptTreeSelectData() {
        SysDept sysDept = new SysDept();
        sysDept.setStatus("0");
        List<SysDept> sysDeptList = deptMapper.selectDeptList(sysDept);
        return getTreeData(sysDeptList, 0);
    }


    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return 树形列表
     */
    private List<SysDept> getTreeTableData(List<SysDept> list, int parentId) {
        List<SysDept> returnList = new ArrayList<>();
        for (SysDept t : list) {
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list 分类表
     * @param t    当前节点
     */
    private void recursionFn(List<SysDept> list, SysDept t) {
        // 得到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysDept n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
        List<SysDept> tlist = new ArrayList<>();
        for (SysDept n : list) {
            if (n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDept> list, SysDept t) {
        return !getChildList(list, t).isEmpty();
    }

    /**
     * 树结构
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return 树结构列表
     */
    private List<TreeData> getTreeData(List<SysDept> list, long parentId) {
        List<TreeData> returnList = new ArrayList<>();
        for (SysDept t : list) {
            if (t.getParentId() == parentId) {
                TreeData treeData = new TreeData();
                treeData.setId(t.getId());
                treeData.setLabel(t.getDeptName());
                treeData.setOrderNum(t.getOrderNum());
                returnList.add(treeData);
                List<TreeData> child = getTreeData(list, t.getId());
                treeData.setChildren(child);
            }
        }
        return returnList;
    }

}
